//
//  EAGLView.m
//  CrazyDice
//
//  Created by Hjelm Daniel on 7/20/10.
//  Copyright __MyCompanyName__ 2010. All rights reserved.
//

#import "EAGLView.h"
#import "MenuView.h"

@implementation EAGLView

@synthesize animating;

@dynamic animationFrameInterval;

// You must implement this method
+ (Class)layerClass
{
    return [CAEAGLLayer class];
}

//The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
- (id)initWithFrame:(CGRect)frame
{
	NSLog(@"initWithFrame");
    if ((self = [super initWithFrame:frame]))
    {
        // Get the layer
        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;

        eaglLayer.opaque = TRUE;
        eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                        [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
		
		
		context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
		
        if (!context || ![EAGLContext setCurrentContext:context])
        {
            [self release];
            return nil;
        }
		
        // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
        glGenFramebuffersOES(1, &defaultFramebuffer);
        glGenRenderbuffersOES(1, &colorRenderbuffer);
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
        glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
        glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
		glEnable(GL_CULL_FACE);
		
		// Texture setup
		NSString * path = [[NSBundle mainBundle] pathForResource: @"texture" ofType:@"pvr"];
		PVRTexture * texture = [[PVRTexture alloc] initWithContentsOfFile: path];
		
		if (texture == nil)
			NSLog(@"Failed to load %@", path);
		else
			NSLog(@"Succeded in loading %@", path);
		
		glBindTexture(GL_TEXTURE_2D, texture.name);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		
		bwdice = [[DiceModel alloc] init];
		background = [[MainBackgroundModel alloc] init];
		
        animating = FALSE;
        displayLinkSupported = FALSE;
        animationFrameInterval = 1;
        displayLink = nil;
        animationTimer = nil;
		
		// add selector
		NSArray *diceSelectorLables = [NSArray arrayWithObjects:@" 1 ", @" 2 ", @" 3 ", @" 4 ", @" 5 ", nil];
		UISegmentedControl *diceSelector = [[[UISegmentedControl alloc] initWithItems:diceSelectorLables] autorelease];
		diceSelector.segmentedControlStyle = UISegmentedControlStyleBar;
		diceSelector.selectedSegmentIndex = 0;
		[diceSelector addTarget:self action:@selector(change:) forControlEvents:UIControlEventValueChanged];
		[self addSubview:diceSelector];
		CGRect controlFrame = diceSelector.frame;
		controlFrame.origin.x = CGRectGetWidth(frame) / 2 - controlFrame.size.width / 2;
		controlFrame.origin.y = CGRectGetHeight(frame) - controlFrame.size.height - 10;
		diceSelector.frame = controlFrame;

        // A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer
        // class is used as fallback when it isn't available.
        NSString *reqSysVer = @"3.1";
        NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
        if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
            displayLinkSupported = TRUE;
    }

    return self;
}

- (void)change:(id)sender {
	[bwdice setTexture:[sender selectedSegmentIndex]];
}
	

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
	NSLog(@"TouchBegan event counts = %d ",[[event touchesForView:self] count]);
	NSLog(@"TouchBegan tounches counts = %d ",[touches count]);
	
	if (CGRectContainsPoint(CGRectMake(120, 20, 120, 60), (CGPoint)[[touches anyObject] locationInView:self])) {
		NSLog(@"back button");
		return;
	}

	if ([touches count]== 2) {
		NSLog(@"Two touches");
	}
	else if ([touches count]==[[event touchesForView:self] count] & [[event touchesForView:self] count] == 1) {
		NSLog(@"One touch");
		//renderer.depth = -7.0f;
		bwdice.rotstop = YES;
	}
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
	UITouch *touch = [[touches allObjects] objectAtIndex:0];
	
	CGPoint currentTouchPosition = [touch locationInView:self];
	
	NSLog(@"Current touchposition = %d", currentTouchPosition);
	
	if (CGRectContainsPoint(CGRectMake(120, 20, 120, 60), currentTouchPosition)) {
		return;
	}
	
	if ([touches count]== 2) {
	}
	
	else if ([touches count]==[[event touchesForView:self] count] & [[event touchesForView:self] count] == 1) {
		NSLog(@"Move to %.2f, %.2f ", [touch locationInView:self].x, [touch locationInView:self].y);
		bwdice.rotstop = NO;
		bwdice.rotspeed = [touch locationInView:self].y/100;
//		if (squareData.touchInside) {
//			// Only move the square to new position when touchBegan is inside the square
//			squareData.pos.x = [touch locationInView:self].x;
//			squareData.pos.y = [touch locationInView:self].y;
//			DEBUGLOG(@"Square Move to %.2f, %.2f ",squareData.pos.x,squareData.pos.y);
//			squareData.rotstop = YES;
//		}
	}	
}



- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
	if (CGRectContainsPoint(CGRectMake(120, 20, 120, 60), (CGPoint)[[touches anyObject] locationInView:self])) {
		NSLog(@"back button");
		[self stopAnimation];
		[(MenuView *)[self superview] showMenu];
		[self removeFromSuperview];
		return;
	}
	
	if ([touches count] == [[event touchesForView:self] count]) {
		NSLog(@"touchesEnded, all fingers up");
	}	
	else {
		NSLog(@"touchesEnded");

	}
}


- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
	NSLog(@"touchesCancelled"); 
}


- (void)drawView:(id)sender
{
	GLenum err;
	
    [EAGLContext setCurrentContext: context];
    
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
    glViewport(0, 0, backingWidth, backingHeight);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
	glFrustumf(-3.2f, 3.2f, -4.8f, 4.8f, 5.0f, 10.0f);
	
    glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	//glScalef(_scale, _scale, 2.0f);
	glTranslatef(0.0f, 0.0f, -5.0f);
    
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
	
	[background drawModel];
	[bwdice drawModel];
	
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
	
	err = glGetError();
	if (err != GL_NO_ERROR)
		NSLog(@"Error in frame. glError: 0x%04X", err);
	
	
}

- (void)layoutSubviews
{
	// Allocate color buffer backing based on the current layer size
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
    [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
	
    if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
    {
        NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
    }
	
    [self drawView:nil];
}

- (NSInteger)animationFrameInterval
{
    return animationFrameInterval;
}

- (void)setAnimationFrameInterval:(NSInteger)frameInterval
{
    // Frame interval defines how many display frames must pass between each time the
    // display link fires. The display link will only fire 30 times a second when the
    // frame internal is two on a display that refreshes 60 times a second. The default
    // frame interval setting of one will fire 60 times a second when the display refreshes
    // at 60 times a second. A frame interval setting of less than one results in undefined
    // behavior.
    if (frameInterval >= 1)
    {
        animationFrameInterval = frameInterval;

        if (animating)
        {
            [self stopAnimation];
            [self startAnimation];
        }
    }
}

- (void)startAnimation
{
    if (!animating)
    {
        if (displayLinkSupported)
        {
            // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed
            // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will
            // not be called in system versions earlier than 3.1.

            displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView:)];
            [displayLink setFrameInterval:animationFrameInterval];
            [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
        }
        else
            animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)((1.0 / 60.0) * animationFrameInterval) target:self selector:@selector(drawView:) userInfo:nil repeats:TRUE];

        animating = TRUE;
    }
}

- (void)stopAnimation
{
    if (animating)
    {
        if (displayLinkSupported)
        {
            [displayLink invalidate];
            displayLink = nil;
        }
        else
        {
            [animationTimer invalidate];
            animationTimer = nil;
        }

        animating = FALSE;
    }
}

- (void)dealloc
{	
	// Tear down GL
    if (defaultFramebuffer)
    {
        glDeleteFramebuffersOES(1, &defaultFramebuffer);
        defaultFramebuffer = 0;
    }
	
    if (colorRenderbuffer)
    {
        glDeleteRenderbuffersOES(1, &colorRenderbuffer);
        colorRenderbuffer = 0;
    }
	
    // Tear down context
    if ([EAGLContext currentContext] == context)
        [EAGLContext setCurrentContext:nil];
	
    [context release];
    context = nil;
	
	[bwdice release];
	bwdice = nil;
	
	[background release];
	background = nil;

    [super dealloc];
}

@end
